home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Date / Calc.php next >
PHP Script  |  2004-10-01  |  53KB  |  1,737 lines

  1. <?php
  2.  
  3. // The constant telling us what day starts the week. Monday (1) is the
  4. // international standard. Redefine this to 0 if you want weeks to
  5. // begin on Sunday.
  6. if (!defined('DATE_CALC_BEGIN_WEEKDAY')) {
  7.     define('DATE_CALC_BEGIN_WEEKDAY', 1);
  8. }
  9.  
  10. /**
  11.  * Date_Calc is a calendar class used to calculate and
  12.  * manipulate calendar dates and retrieve dates in a calendar
  13.  * format. It does not rely on 32-bit system date stamps, so
  14.  * you can display calendars and compare dates that date
  15.  * pre 1970 and post 2038.
  16.  *
  17.  * This source file is subject to version 2.02 of the PHP license,
  18.  * that is bundled with this package in the file LICENSE, and is
  19.  * available at through the world-wide-web at
  20.  * http://www.php.net/license/2_02.txt.
  21.  * If you did not receive a copy of the PHP license and are unable to
  22.  * obtain it through the world-wide-web, please send a note to
  23.  * license@php.net so we can mail you a copy immediately.
  24.  *
  25.  * Copyright (c) 1999, 2002, 2003 ispi
  26.  *
  27.  * @access public
  28.  *
  29.  * @version 1.2.6
  30.  * @author Monte Ohrt <monte@ispi.net>
  31.  */
  32.  
  33. class Date_Calc
  34. {
  35.     /**
  36.      * Returns the current local date. NOTE: This function
  37.      * retrieves the local date using strftime(), which may
  38.      * or may not be 32-bit safe on your system.
  39.      *
  40.      * @param string the strftime() format to return the date
  41.      *
  42.      * @access public
  43.      *
  44.      * @return string the current date in specified format
  45.      */
  46.  
  47.     function dateNow($format='%Y%m%d')
  48.     {
  49.         return(strftime($format,time()));
  50.  
  51.     } // end func dateNow
  52.  
  53.      /**
  54.      * Returns true for valid date, false for invalid date.
  55.      *
  56.      * @param string year in format CCYY
  57.      * @param string month in format MM
  58.      * @param string day in format DD
  59.      *
  60.      * @access public
  61.      *
  62.      * @return boolean true/false
  63.      */
  64.  
  65.     function isValidDate($day, $month, $year)
  66.     {
  67.         if ($year < 0 || $year > 9999) {
  68.             return false;
  69.         }
  70.         if (!checkdate($month,$day,$year)) {
  71.             return false;
  72.         }
  73.  
  74.         return true;
  75.     } // end func isValidDate
  76.  
  77.      /**
  78.      * Returns true for a leap year, else false
  79.      *
  80.      * @param string year in format CCYY
  81.      *
  82.      * @access public
  83.      *
  84.      * @return boolean true/false
  85.      */
  86.  
  87.     function isLeapYear($year='')
  88.     {
  89.         if (empty($year)) {
  90.             $year = Date_Calc::dateNow('%Y');
  91.         }
  92.  
  93.         if (preg_match('/\D/',$year)) {
  94.             return false;
  95.         }
  96.  
  97.         if ($year < 1000) {
  98.             return false;
  99.         }
  100.  
  101.         if ($year < 1582) {
  102.             // pre Gregorio XIII - 1582
  103.             return ($year % 4 == 0);
  104.         } else {
  105.             // post Gregorio XIII - 1582
  106.             return ( (($year % 4 == 0) and ($year % 100 != 0)) or ($year % 400 == 0) );
  107.         }
  108.     } // end func isLeapYear
  109.  
  110.     /**
  111.      * Determines if given date is a future date from now.
  112.      *
  113.      * @param string day in format DD
  114.      * @param string month in format MM
  115.      * @param string year in format CCYY
  116.      *
  117.      * @access public
  118.      *
  119.      * @return boolean true/false
  120.      */
  121.  
  122.     function isFutureDate($day,$month,$year)
  123.     {
  124.         $this_year = Date_Calc::dateNow('%Y');
  125.         $this_month = Date_Calc::dateNow('%m');
  126.         $this_day = Date_Calc::dateNow('%d');
  127.  
  128.         if ($year > $this_year) {
  129.             return true;
  130.         } elseif ($year == $this_year) {
  131.             if ($month > $this_month) {
  132.                 return true;
  133.             } elseif ($month == $this_month) {
  134.                 if ($day > $this_day) {
  135.                     return true;
  136.                 }
  137.             }
  138.         }
  139.  
  140.         return false;
  141.     } // end func isFutureDate
  142.  
  143.     /**
  144.      * Determines if given date is a past date from now.
  145.      *
  146.      * @param string day in format DD
  147.      * @param string month in format MM
  148.      * @param string year in format CCYY
  149.      *
  150.      * @access public
  151.      *
  152.      * @return boolean true/false
  153.      */
  154.  
  155.     function isPastDate($day,$month,$year)
  156.     {
  157.         $this_year = Date_Calc::dateNow('%Y');
  158.         $this_month = Date_Calc::dateNow('%m');
  159.         $this_day = Date_Calc::dateNow('%d');
  160.  
  161.         if ($year < $this_year) {
  162.             return true;
  163.         } elseif ($year == $this_year) {
  164.             if ($month < $this_month) {
  165.                 return true;
  166.             } elseif ($month == $this_month) {
  167.                 if ($day < $this_day) {
  168.                     return true;
  169.                 }
  170.             }
  171.         }
  172.  
  173.         return false;
  174.     } // end func isPastDate
  175.  
  176.     /**
  177.      * Returns day of week for given date, 0=Sunday
  178.      *
  179.      * @param string day in format DD, default is current local day
  180.      * @param string month in format MM, default is current local month
  181.      * @param string year in format CCYY, default is current local year
  182.      *
  183.      * @access public
  184.      *
  185.      * @return int $weekday_number
  186.      */
  187.  
  188.     function dayOfWeek($day='',$month='',$year='')
  189.     {
  190.         if (empty($year)) {
  191.             $year = Date_Calc::dateNow('%Y');
  192.         }
  193.         if (empty($month)) {
  194.             $month = Date_Calc::dateNow('%m');
  195.         }
  196.         if (empty($day)) {
  197.             $day = Date_Calc::dateNow('%d');
  198.         }
  199.  
  200.         if ($month > 2) {
  201.             $month -= 2;
  202.         } else {
  203.             $month += 10;
  204.             $year--;
  205.         }
  206.  
  207.         $day = ( floor((13 * $month - 1) / 5) +
  208.             $day + ($year % 100) +
  209.             floor(($year % 100) / 4) +
  210.             floor(($year / 100) / 4) - 2 *
  211.             floor($year / 100) + 77);
  212.  
  213.         $weekday_number = (($day - 7 * floor($day / 7)));
  214.  
  215.         return $weekday_number;
  216.     } // end func dayOfWeek
  217.  
  218.     /**
  219.      * Returns week of the year, first Sunday is first day of first week
  220.      *
  221.      * @param string day in format DD, default is current local day
  222.      * @param string month in format MM, default is current local month
  223.      * @param string year in format CCYY, default is current local year
  224.      *
  225.      * @access public
  226.      *
  227.      * @return integer $week_number
  228.      */
  229.  
  230.     function weekOfYear($day='',$month='',$year='')
  231.     {
  232.         if (empty($year)) {
  233.             $year = Date_Calc::dateNow('%Y');
  234.         }
  235.         if (empty($month)) {
  236.             $month = Date_Calc::dateNow('%m');
  237.         }
  238.         if (empty($day)) {
  239.             $day = Date_Calc::dateNow('%d');
  240.         }
  241.         $iso    = Date_Calc::gregorianToISO($day, $month, $year);
  242.         $parts  = explode('-',$iso);
  243.         $week_number = intval($parts[1]);
  244.         return $week_number;
  245.     } // end func weekOfYear
  246.  
  247.     /**
  248.      * Returns number of days since 31 December of year before given date.
  249.      *
  250.      * @param string day in format DD, default is current local day
  251.      * @param string month in format MM, default is current local month
  252.      * @param string year in format CCYY, default is current local year
  253.      *
  254.      * @access public
  255.      *
  256.      * @return int $julian
  257.      */
  258.  
  259.     function julianDate($day='',$month='',$year='')
  260.     {
  261.         if (empty($year)) {
  262.             $year = Date_Calc::dateNow('%Y');
  263.         }
  264.         if (empty($month)) {
  265.             $month = Date_Calc::dateNow('%m');
  266.         }
  267.         if (empty($day)) {
  268.             $day = Date_Calc::dateNow('%d');
  269.         }
  270.  
  271.         $days = array(0,31,59,90,120,151,181,212,243,273,304,334);
  272.  
  273.         $julian = ($days[$month - 1] + $day);
  274.  
  275.         if ($month > 2 && Date_Calc::isLeapYear($year)) {
  276.             $julian++;
  277.         }
  278.  
  279.         return($julian);
  280.     } // end func julianDate
  281.  
  282.     /**
  283.      * Returns quarter of the year for given date
  284.      *
  285.      * @param string day in format DD, default is current local day
  286.      * @param string month in format MM, default is current local month
  287.      * @param string year in format CCYY, default is current local year
  288.      *
  289.      * @access public
  290.      *
  291.      * @return int $year_quarter
  292.      */
  293.  
  294.     function quarterOfYear($day='',$month='',$year='')
  295.     {
  296.         if (empty($year)) {
  297.             $year = Date_Calc::dateNow('%Y');
  298.         }
  299.         if (empty($month)) {
  300.             $month = Date_Calc::dateNow('%m');
  301.         }
  302.         if (empty($day)) {
  303.             $day = Date_Calc::dateNow('%d');
  304.         }
  305.  
  306.         $year_quarter = (intval(($month - 1) / 3 + 1));
  307.  
  308.         return $year_quarter;
  309.     } // end func quarterOfYear
  310.  
  311.     /**
  312.      * Returns date of begin of next month of given date.
  313.      *
  314.      * @param string day in format DD, default is current local day
  315.      * @param string month in format MM, default is current local month
  316.      * @param string year in format CCYY, default is current local year
  317.      * @param string format for returned date
  318.      *
  319.      * @access public
  320.      *
  321.      * @return string date in given format
  322.      */
  323.  
  324.     function beginOfNextMonth($day='',$month='',$year='',$format='%Y%m%d')
  325.     {
  326.         if (empty($year)) {
  327.             $year = Date_Calc::dateNow('%Y');
  328.         }
  329.         if (empty($month)) {
  330.             $month = Date_Calc::dateNow('%m');
  331.         }
  332.         if (empty($day)) {
  333.             $day = Date_Calc::dateNow('%d');
  334.         }
  335.  
  336.         if ($month < 12) {
  337.             $month++;
  338.             $day=1;
  339.         } else {
  340.             $year++;
  341.             $month=1;
  342.             $day=1;
  343.         }
  344.  
  345.         return Date_Calc::dateFormat($day,$month,$year,$format);
  346.     } // end func beginOfNextMonth
  347.  
  348.     /**
  349.      * Returns date of the last day of next month of given date.
  350.      *
  351.      * @param string day in format DD, default is current local day
  352.      * @param string month in format MM, default is current local month
  353.      * @param string year in format CCYY, default is current local year
  354.      * @param string format for returned date
  355.      *
  356.      * @access public
  357.      *
  358.      * @return string date in given format
  359.      */
  360.  
  361.     function endOfNextMonth($day='',$month='',$year='',$format='%Y%m%d')
  362.     {
  363.         if (empty($year)) {
  364.             $year = Date_Calc::dateNow('%Y');
  365.         }
  366.         if (empty($month)) {
  367.             $month = Date_Calc::dateNow('%m');
  368.         }
  369.         if (empty($day)) {
  370.             $day = Date_Calc::dateNow('%d');
  371.         }
  372.  
  373.         if ($month < 12) {
  374.             $month++;
  375.         } else {
  376.             $year++;
  377.             $month=1;
  378.         }
  379.  
  380.         $day = Date_Calc::daysInMonth($month,$year);
  381.  
  382.         return Date_Calc::dateFormat($day,$month,$year,$format);
  383.     } // end func endOfNextMonth
  384.  
  385.     /**
  386.      * Returns date of the first day of previous month of given date.
  387.      *
  388.      * @param string day in format DD, default is current local day
  389.      * @param string month in format MM, default is current local month
  390.      * @param string year in format CCYY, default is current local year
  391.      * @param string format for returned date
  392.      *
  393.      * @access public
  394.      *
  395.      * @return string date in given format
  396.      */
  397.  
  398.     function beginOfPrevMonth($day='',$month='',$year='',$format='%Y%m%d')
  399.     {
  400.         if (empty($year)) {
  401.             $year = Date_Calc::dateNow('%Y');
  402.         }
  403.         if (empty($month)) {
  404.             $month = Date_Calc::dateNow('%m');
  405.         }
  406.         if (empty($day)) {
  407.             $day = Date_Calc::dateNow('%d');
  408.         }
  409.  
  410.         if ($month > 1) {
  411.             $month--;
  412.             $day=1;
  413.         } else {
  414.             $year--;
  415.             $month=12;
  416.             $day=1;
  417.         }
  418.  
  419.         return Date_Calc::dateFormat($day,$month,$year,$format);
  420.     } // end func beginOfPrevMonth
  421.  
  422.     /**
  423.      * Returns date of the last day of previous month for given date.
  424.      *
  425.      * @param string day in format DD, default is current local day
  426.      * @param string month in format MM, default is current local month
  427.      * @param string year in format CCYY, default is current local year
  428.      * @param string format for returned date
  429.      *
  430.      * @access public
  431.      *
  432.      * @return string date in given format
  433.      */
  434.  
  435.     function endOfPrevMonth($day='',$month='',$year='',$format='%Y%m%d')
  436.     {
  437.         if (empty($year)) {
  438.             $year = Date_Calc::dateNow('%Y');
  439.         }
  440.         if (empty($month)) {
  441.             $month = Date_Calc::dateNow('%m');
  442.         }
  443.         if (empty($day)) {
  444.             $day = Date_Calc::dateNow('%d');
  445.         }
  446.  
  447.         if ($month > 1) {
  448.             $month--;
  449.         } else {
  450.             $year--;
  451.             $month=12;
  452.         }
  453.  
  454.         $day = Date_Calc::daysInMonth($month,$year);
  455.  
  456.         return Date_Calc::dateFormat($day,$month,$year,$format);
  457.     } // end func endOfPrevMonth
  458.  
  459.     /**
  460.      * Returns date of the next weekday of given date,
  461.      * skipping from Friday to Monday.
  462.      *
  463.      * @param string day in format DD, default is current local day
  464.      * @param string month in format MM, default is current local month
  465.      * @param string year in format CCYY, default is current local year
  466.      * @param string format for returned date
  467.      *
  468.      * @access public
  469.      *
  470.      * @return string date in given format
  471.      */
  472.  
  473.     function nextWeekday($day='',$month='',$year='',$format='%Y%m%d')
  474.     {
  475.         if (empty($year)) {
  476.             $year = Date_Calc::dateNow('%Y');
  477.         }
  478.         if (empty($month)) {
  479.             $month = Date_Calc::dateNow('%m');
  480.         }
  481.         if (empty($day)) {
  482.             $day = Date_Calc::dateNow('%d');
  483.         }
  484.  
  485.         $days = Date_Calc::dateToDays($day,$month,$year);
  486.  
  487.         if (Date_Calc::dayOfWeek($day,$month,$year) == 5) {
  488.             $days += 3;
  489.         } elseif (Date_Calc::dayOfWeek($day,$month,$year) == 6) {
  490.             $days += 2;
  491.         } else {
  492.             $days += 1;
  493.         }
  494.  
  495.         return(Date_Calc::daysToDate($days,$format));
  496.     } // end func nextWeekday
  497.  
  498.     /**
  499.      * Returns date of the previous weekday,
  500.      * skipping from Monday to Friday.
  501.      *
  502.      * @param string day in format DD, default is current local day
  503.      * @param string month in format MM, default is current local month
  504.      * @param string year in format CCYY, default is current local year
  505.      * @param string format for returned date
  506.      *
  507.      * @access public
  508.      *
  509.      * @return string date in given format
  510.      */
  511.  
  512.     function prevWeekday($day='',$month='',$year='',$format='%Y%m%d')
  513.     {
  514.         if (empty($year)) {
  515.             $year = Date_Calc::dateNow('%Y');
  516.         }
  517.         if (empty($month)) {
  518.             $month = Date_Calc::dateNow('%m');
  519.         }
  520.         if (empty($day)) {
  521.             $day = Date_Calc::dateNow('%d');
  522.         }
  523.  
  524.         $days = Date_Calc::dateToDays($day,$month,$year);
  525.  
  526.         if (Date_Calc::dayOfWeek($day,$month,$year) == 1) {
  527.             $days -= 3;
  528.         } elseif (Date_Calc::dayOfWeek($day,$month,$year) == 0) {
  529.             $days -= 2;
  530.         } else {
  531.             $days -= 1;
  532.         }
  533.  
  534.         return(Date_Calc::daysToDate($days,$format));
  535.     } // end func prevWeekday
  536.  
  537.     /**
  538.      * Returns date of the next specific day of the week
  539.      * from the given date.
  540.      *
  541.      * @param int day of week, 0=Sunday
  542.      * @param string day in format DD, default is current local day
  543.      * @param string month in format MM, default is current local month
  544.      * @param string year in format CCYY, default is current local year
  545.      * @param boolean onOrAfter if true and days are same, returns current day
  546.      * @param string format for returned date
  547.      *
  548.      * @access public
  549.      *
  550.      * @return string date in given format
  551.      */
  552.  
  553.     function nextDayOfWeek($dow,$day='',$month='',$year='',$format='%Y%m%d',$onOrAfter=false)
  554.     {
  555.         if (empty($year)) {
  556.             $year = Date_Calc::dateNow('%Y');
  557.         }
  558.         if (empty($month)) {
  559.             $month = Date_Calc::dateNow('%m');
  560.         }
  561.         if (empty($day)) {
  562.             $day = Date_Calc::dateNow('%d');
  563.         }
  564.  
  565.         $days = Date_Calc::dateToDays($day,$month,$year);
  566.         $curr_weekday = Date_Calc::dayOfWeek($day,$month,$year);
  567.  
  568.         if ($curr_weekday == $dow) {
  569.             if (!$onOrAfter) {
  570.                 $days += 7;
  571.             }
  572.         }
  573.         elseif ($curr_weekday > $dow) {
  574.             $days += 7 - ( $curr_weekday - $dow );
  575.         } else {
  576.             $days += $dow - $curr_weekday;
  577.         }
  578.  
  579.         return(Date_Calc::daysToDate($days,$format));
  580.     } // end func nextDayOfWeek
  581.  
  582.     /**
  583.      * Returns date of the previous specific day of the week
  584.      * from the given date.
  585.      *
  586.      * @param int day of week, 0=Sunday
  587.      * @param string day in format DD, default is current local day
  588.      * @param string month in format MM, default is current local month
  589.      * @param string year in format CCYY, default is current local year
  590.      * @param boolean onOrBefore if true and days are same, returns current day
  591.      * @param string format for returned date
  592.      *
  593.      * @access public
  594.      *
  595.      * @return string date in given format
  596.      */
  597.  
  598.     function prevDayOfWeek($dow,$day='',$month='',$year='',$format='%Y%m%d',$onOrBefore=false)
  599.     {
  600.         if (empty($year)) {
  601.             $year = Date_Calc::dateNow('%Y');
  602.         }
  603.         if (empty($month)) {
  604.             $month = Date_Calc::dateNow('%m');
  605.         }
  606.         if (empty($day)) {
  607.             $day = Date_Calc::dateNow('%d');
  608.         }
  609.  
  610.         $days = Date_Calc::dateToDays($day,$month,$year);
  611.         $curr_weekday = Date_Calc::dayOfWeek($day,$month,$year);
  612.  
  613.         if ($curr_weekday == $dow) {
  614.             if (!$onOrBefore) {
  615.                 $days -= 7;
  616.             }
  617.         }
  618.         elseif ($curr_weekday < $dow) {
  619.             $days -= 7 - ( $dow - $curr_weekday );
  620.         } else {
  621.             $days -= $curr_weekday - $dow;
  622.         }
  623.  
  624.         return(Date_Calc::daysToDate($days,$format));
  625.     } // end func prevDayOfWeek
  626.  
  627.     /**
  628.      * Returns date of the next specific day of the week
  629.      * on or after the given date.
  630.      *
  631.      * @param int day of week, 0=Sunday
  632.      * @param string day in format DD, default is current local day
  633.      * @param string month in format MM, default is current local month
  634.      * @param string year in format CCYY, default is current local year
  635.      * @param string format for returned date
  636.      *
  637.      * @access public
  638.      *
  639.      * @return string date in given format
  640.      */
  641.  
  642.     function nextDayOfWeekOnOrAfter($dow,$day='',$month='',$year='',$format='%Y%m%d')
  643.     {
  644.         return(Date_Calc::nextDayOfWeek($dow,$day,$month,$year,$format,true));
  645.     } // end func nextDayOfWeekOnOrAfter
  646.  
  647.     /**
  648.      * Returns date of the previous specific day of the week
  649.      * on or before the given date.
  650.      *
  651.      * @param int day of week, 0=Sunday
  652.      * @param string day in format DD, default is current local day
  653.      * @param string month in format MM, default is current local month
  654.      * @param string year in format CCYY, default is current local year
  655.      * @param string format for returned date
  656.      *
  657.      * @access public
  658.      *
  659.      * @return string date in given format
  660.      */
  661.  
  662.     function prevDayOfWeekOnOrBefore($dow,$day='',$month='',$year='',$format='%Y%m%d')
  663.     {
  664.         return(Date_Calc::prevDayOfWeek($dow,$day,$month,$year,$format,true));
  665.     } // end func prevDayOfWeekOnOrAfter
  666.  
  667.     /**
  668.      * Returns date of day after given date.
  669.      *
  670.      * @param string day in format DD, default is current local day
  671.      * @param string month in format MM, default is current local month
  672.      * @param string year in format CCYY, default is current local year
  673.      * @param string format for returned date
  674.      *
  675.      * @access public
  676.      *
  677.      * @return string date in given format
  678.      */
  679.  
  680.     function nextDay($day='',$month='',$year='',$format='%Y%m%d')
  681.     {
  682.         if (empty($year)) {
  683.             $year = Date_Calc::dateNow('%Y');
  684.         }
  685.         if (empty($month)) {
  686.             $month = Date_Calc::dateNow('%m');
  687.         }
  688.         if (empty($day)) {
  689.             $day = Date_Calc::dateNow('%d');
  690.         }
  691.  
  692.         $days = Date_Calc::dateToDays($day,$month,$year);
  693.  
  694.         return(Date_Calc::daysToDate($days + 1,$format));
  695.     } // end func nextDay
  696.  
  697.     /**
  698.      * Returns date of day before given date.
  699.      *
  700.      * @param string day in format DD, default is current local day
  701.      * @param string month in format MM, default is current local month
  702.      * @param string year in format CCYY, default is current local year
  703.      * @param string format for returned date
  704.      *
  705.      * @access public
  706.      *
  707.      * @return string date in given format
  708.      */
  709.  
  710.     function prevDay($day='',$month='',$year='',$format='%Y%m%d')
  711.     {
  712.         if (empty($year)) {
  713.             $year = Date_Calc::dateNow('%Y');
  714.         }
  715.         if (empty($month)) {
  716.             $month = Date_Calc::dateNow('%m');
  717.         }
  718.         if (empty($day)) {
  719.             $day = Date_Calc::dateNow('%d');
  720.         }
  721.  
  722.         $days = Date_Calc::dateToDays($day,$month,$year);
  723.  
  724.         return(Date_Calc::daysToDate($days - 1,$format));
  725.     } // end func prevDay
  726.  
  727.     /**
  728.      * Sets century for 2 digit year.
  729.      * 51-99 is 19, else 20
  730.      *
  731.      * @param string 2 digit year
  732.      *
  733.      * @access public
  734.      *
  735.      * @return string 4 digit year
  736.      */
  737.  
  738.     function defaultCentury($year)
  739.     {
  740.         if (strlen($year) == 1) {
  741.             $year = "0$year";
  742.         }
  743.         if ($year > 50) {
  744.             return( "19$year" );
  745.         } else {
  746.             return( "20$year" );
  747.         }
  748.     } // end func defaultCentury
  749.  
  750.     /**
  751.      * Returns number of days between two given dates.
  752.      *
  753.     * @param string $day1   day in format DD
  754.     * @param string $month1 month in format MM
  755.     * @param string $year1  year in format CCYY
  756.     * @param string $day2   day in format DD
  757.     * @param string $month2 month in format MM
  758.     * @param string $year2  year in format CCYY
  759.      *
  760.      * @access public
  761.      *
  762.      * @return int absolute number of days between dates,
  763.      *      -1 if there is an error.
  764.      */
  765.  
  766.     function dateDiff($day1,$month1,$year1,$day2,$month2,$year2)
  767.     {
  768.         if (!Date_Calc::isValidDate($day1,$month1,$year1)) {
  769.             return -1;
  770.         }
  771.         if (!Date_Calc::isValidDate($day2,$month2,$year2)) {
  772.             return -1;
  773.         }
  774.  
  775.         return(abs((Date_Calc::dateToDays($day1,$month1,$year1))
  776.                     - (Date_Calc::dateToDays($day2,$month2,$year2))));
  777.     } // end func dateDiff
  778.  
  779.     /**
  780.     * Compares two dates
  781.     *
  782.     * @param string $day1   day in format DD
  783.     * @param string $month1 month in format MM
  784.     * @param string $year1  year in format CCYY
  785.     * @param string $day2   day in format DD
  786.     * @param string $month2 month in format MM
  787.     * @param string $year2  year in format CCYY
  788.     *
  789.     * @access public
  790.     * @return int 0 on equality, 1 if date 1 is greater, -1 if smaller
  791.     */
  792.     function compareDates($day1,$month1,$year1,$day2,$month2,$year2)
  793.     {
  794.         $ndays1 = Date_Calc::dateToDays($day1, $month1, $year1);
  795.         $ndays2 = Date_Calc::dateToDays($day2, $month2, $year2);
  796.         if ($ndays1 == $ndays2) {
  797.             return 0;
  798.         }
  799.         return ($ndays1 > $ndays2) ? 1 : -1;
  800.     } // end func compareDates
  801.  
  802.     /**
  803.      * Find the number of days in the given month.
  804.      *
  805.      * @param string month in format MM, default is current local month
  806.      * @param string year in format CCYY, default is current local year
  807.      *
  808.      * @access public
  809.      *
  810.      * @return int number of days
  811.      */
  812.  
  813.     function daysInMonth($month='',$year='')
  814.     {
  815.         if (empty($year)) {
  816.             $year = Date_Calc::dateNow('%Y');
  817.         }
  818.         if (empty($month)) {
  819.             $month = Date_Calc::dateNow('%m');
  820.         }
  821.  
  822.         if ($year == 1582 && $month == 10) {
  823.             return 21;  // October 1582 only had 1st-4th and 15th-31st
  824.         }
  825.  
  826.         if ($month == 2) {
  827.             if (Date_Calc::isLeapYear($year)) {
  828.                 return 29;
  829.              } else {
  830.                 return 28;
  831.             }
  832.         } elseif ($month == 4 or $month == 6 or $month == 9 or $month == 11) {
  833.             return 30;
  834.         } else {
  835.             return 31;
  836.         }
  837.     } // end func daysInMonth
  838.  
  839.     /**
  840.      * Returns the number of rows on a calendar month. Useful for
  841.      * determining the number of rows when displaying a typical
  842.      * month calendar.
  843.      *
  844.      * @param string month in format MM, default is current local month
  845.      * @param string year in format CCYY, default is current local year
  846.      *
  847.      * @access public
  848.      *
  849.      * @return int number of weeks
  850.      */
  851.  
  852.     function weeksInMonth($month='',$year='')
  853.     {
  854.         if (empty($year)) {
  855.             $year = Date_Calc::dateNow('%Y');
  856.         }
  857.         if (empty($month)) {
  858.             $month = Date_Calc::dateNow('%m');
  859.         }
  860.         $FDOM = Date_Calc::firstOfMonthWeekday($month, $year);
  861.         if (DATE_CALC_BEGIN_WEEKDAY==1 && $FDOM==0) {
  862.             $first_week_days = 7 - $FDOM + DATE_CALC_BEGIN_WEEKDAY;
  863.             $weeks = 1;
  864.         } elseif (DATE_CALC_BEGIN_WEEKDAY==0 && $FDOM == 6) {
  865.             $first_week_days = 7 - $FDOM + DATE_CALC_BEGIN_WEEKDAY;
  866.             $weeks = 1;
  867.         } else {
  868.             $first_week_days = DATE_CALC_BEGIN_WEEKDAY - $FDOM;
  869.             $weeks = 0;
  870.         }
  871.         $first_week_days %= 7;
  872.         return (ceil((Date_Calc::daysInMonth($month, $year) - $first_week_days) / 7) + $weeks);
  873.     } // end func weeksInMonth
  874.  
  875.     /**
  876.      * Find the day of the week for the first of the month of given date.
  877.      *
  878.      * @param string month in format MM, default is current local month
  879.      * @param string year in format CCYY, default is current local year
  880.      *
  881.      * @access public
  882.      *
  883.      * @return int number of weekday for the first day, 0=Sunday
  884.      */
  885.  
  886.     function firstOfMonthWeekday($month='',$year='')
  887.     {
  888.         if (empty($year)) {
  889.             $year = Date_Calc::dateNow('%Y');
  890.         }
  891.         if (empty($month)) {
  892.             $month = Date_Calc::dateNow('%m');
  893.         }
  894.  
  895.         return(Date_Calc::dayOfWeek('01',$month,$year));
  896.     } // end func firstOfMonthWeekday
  897.  
  898.     /**
  899.      * Return date of first day of month of given date.
  900.      *
  901.      * @param string month in format MM, default is current local month
  902.      * @param string year in format CCYY, default is current local year
  903.      * @param string format for returned date
  904.      *
  905.      * @access public
  906.      *
  907.      * @return string date in given format
  908.      */
  909.  
  910.     function beginOfMonth($month='',$year='',$format='%Y%m%d')
  911.     {
  912.         if (empty($year)) {
  913.             $year = Date_Calc::dateNow('%Y');
  914.         }
  915.         if (empty($month)) {
  916.             $month = Date_Calc::dateNow('%m');
  917.         }
  918.  
  919.         return(Date_Calc::dateFormat('01',$month,$year,$format));
  920.     } // end of func beginOfMonth
  921.  
  922.     /**
  923.      * Find the month day of the beginning of week for given date,
  924.      * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
  925.      *
  926.      * @param string day in format DD, default is current local day
  927.      * @param string month in format MM, default is current local month
  928.      * @param string year in format CCYY, default is current local year
  929.      * @param string format for returned date
  930.      *
  931.      * @access public
  932.      *
  933.      * @return string date in given format
  934.      */
  935.  
  936.     function beginOfWeek($day='',$month='',$year='',$format='%Y%m%d')
  937.     {
  938.         if (empty($year)) {
  939.             $year = Date_Calc::dateNow('%Y');
  940.         }
  941.         if (empty($month)) {
  942.             $month = Date_Calc::dateNow('%m');
  943.         }
  944.         if (empty($day)) {
  945.             $day = Date_Calc::dateNow('%d');
  946.         }
  947.  
  948.         $this_weekday = Date_Calc::dayOfWeek($day,$month,$year);
  949.  
  950.         $interval = (7 - DATE_CALC_BEGIN_WEEKDAY + $this_weekday) % 7;
  951.  
  952.         return(Date_Calc::daysToDate(Date_Calc::dateToDays($day,$month,$year) - $interval,$format));
  953.     } // end of func beginOfWeek
  954.  
  955.     /**
  956.      * Find the month day of the end of week for given date,
  957.      * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday
  958.      * of following month.)
  959.      *
  960.      * @param string day in format DD, default is current local day
  961.      * @param string month in format MM, default is current local month
  962.      * @param string year in format CCYY, default is current local year
  963.      * @param string format for returned date
  964.      *
  965.      * @access public
  966.      *
  967.      * @return string date in given format
  968.      */
  969.  
  970.     function endOfWeek($day='',$month='',$year='',$format='%Y%m%d')
  971.     {
  972.         if (empty($year)) {
  973.             $year = Date_Calc::dateNow('%Y');
  974.         }
  975.         if (empty($month)) {
  976.             $month = Date_Calc::dateNow('%m');
  977.         }
  978.         if (empty($day)) {
  979.             $day = Date_Calc::dateNow('%d');
  980.         }
  981.  
  982.  
  983.         $this_weekday = Date_Calc::dayOfWeek($day,$month,$year);
  984.  
  985.         $interval = (6 + DATE_CALC_BEGIN_WEEKDAY - $this_weekday) % 7;
  986.  
  987.         return(Date_Calc::daysToDate(Date_Calc::dateToDays($day,$month,$year) + $interval,$format));
  988.     } // end func endOfWeek
  989.  
  990.     /**
  991.      * Find the month day of the beginning of week after given date,
  992.      * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
  993.      *
  994.      * @param string day in format DD, default is current local day
  995.      * @param string month in format MM, default is current local month
  996.      * @param string year in format CCYY, default is current local year
  997.      * @param string format for returned date
  998.      *
  999.      * @access public
  1000.      *
  1001.      * @return string date in given format
  1002.      */
  1003.  
  1004.     function beginOfNextWeek($day='',$month='',$year='',$format='%Y%m%d')
  1005.     {
  1006.         if (empty($year)) {
  1007.             $year = Date_Calc::dateNow("%Y");
  1008.         }
  1009.         if (empty($month)) {
  1010.             $month = Date_Calc::dateNow("%m");
  1011.         }
  1012.         if (empty($day)) {
  1013.             $day = Date_Calc::dateNow("%d");
  1014.         }
  1015.  
  1016.         $date = Date_Calc::daysToDate(
  1017.                     Date_Calc::dateToDays($day+7,$month,$year),"%Y%m%d"
  1018.                 );
  1019.  
  1020.         $next_week_year = substr($date,0,4);
  1021.         $next_week_month = substr($date,4,2);
  1022.         $next_week_day = substr($date,6,2);
  1023.  
  1024.         return Date_Calc::beginOfWeek(
  1025.                             $next_week_day,$next_week_month,$next_week_year,
  1026.                             $format
  1027.                         );
  1028.  
  1029.         $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day+7,$month,$year),"%Y%m%d");
  1030.     } // end func beginOfNextWeek
  1031.  
  1032.     /**
  1033.      * Find the month day of the beginning of week before given date,
  1034.      * using DATE_CALC_BEGIN_WEEKDAY. (can return weekday of prev month.)
  1035.      *
  1036.      * @param string day in format DD, default is current local day
  1037.      * @param string month in format MM, default is current local month
  1038.      * @param string year in format CCYY, default is current local year
  1039.      * @param string format for returned date
  1040.      *
  1041.      * @access public
  1042.      *
  1043.      * @return string date in given format
  1044.      */
  1045.  
  1046.     function beginOfPrevWeek($day='',$month='',$year='',$format='%Y%m%d')
  1047.     {
  1048.         if (empty($year)) {
  1049.             $year = Date_Calc::dateNow("%Y");
  1050.         }
  1051.         if (empty($month)) {
  1052.             $month = Date_Calc::dateNow("%m");
  1053.         }
  1054.         if (empty($day)) {
  1055.             $day = Date_Calc::dateNow("%d");
  1056.         }
  1057.  
  1058.         $date = Date_Calc::daysToDate(
  1059.                         Date_Calc::dateToDays($day-7,$month,$year),"%Y%m%d"
  1060.                     );
  1061.  
  1062.         $prev_week_year = substr($date,0,4);
  1063.         $prev_week_month = substr($date,4,2);
  1064.         $prev_week_day = substr($date,6,2);
  1065.  
  1066.         return Date_Calc::beginOfWeek($prev_week_day,$prev_week_month,$prev_week_year,$format);
  1067.  
  1068.  
  1069.         $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day-7,$month,$year),"%Y%m%d");
  1070.     } // end func beginOfPrevWeek
  1071.  
  1072.     /**
  1073.      * Return an array with days in week
  1074.      *
  1075.      * @param string day in format DD, default is current local day
  1076.      * @param string month in format MM, default is current local month
  1077.      * @param string year in format CCYY, default is current local year
  1078.      * @param string format for returned date
  1079.      *
  1080.      * @access public
  1081.      *
  1082.      * @return array $week[$weekday]
  1083.      */
  1084.  
  1085.     function getCalendarWeek($day='',$month='',$year='',$format='%Y%m%d')
  1086.     {
  1087.         if (empty($year)) {
  1088.             $year = Date_Calc::dateNow('%Y');
  1089.         }
  1090.         if (empty($month)) {
  1091.             $month = Date_Calc::dateNow('%m');
  1092.         }
  1093.         if (empty($day)) {
  1094.             $day = Date_Calc::dateNow('%d');
  1095.         }
  1096.  
  1097.         $week_array = array();
  1098.  
  1099.         // date for the column of week
  1100.  
  1101.         $curr_day = Date_Calc::beginOfWeek($day,$month,$year,'%E');
  1102.  
  1103.         for($counter=0; $counter <= 6; $counter++) {
  1104.             $week_array[$counter] = Date_Calc::daysToDate($curr_day,$format);
  1105.             $curr_day++;
  1106.         }
  1107.  
  1108.         return $week_array;
  1109.     } // end func getCalendarWeek
  1110.  
  1111.     /**
  1112.      * Return a set of arrays to construct a calendar month for
  1113.      * the given date.
  1114.      *
  1115.      * @param string month in format MM, default is current local month
  1116.      * @param string year in format CCYY, default is current local year
  1117.      * @param string format for returned date
  1118.      *
  1119.      * @access public
  1120.      *
  1121.      * @return array $month[$row][$col]
  1122.      */
  1123.  
  1124.     function getCalendarMonth($month='',$year='',$format='%Y%m%d')
  1125.     {
  1126.         if (empty($year)) {
  1127.             $year = Date_Calc::dateNow('%Y');
  1128.         }
  1129.         if (empty($month)) {
  1130.             $month = Date_Calc::dateNow('%m');
  1131.         }
  1132.  
  1133.         $month_array = array();
  1134.  
  1135.         // date for the first row, first column of calendar month
  1136.         if (DATE_CALC_BEGIN_WEEKDAY == 1) {
  1137.             if (Date_Calc::firstOfMonthWeekday($month,$year) == 0) {
  1138.                 $curr_day = Date_Calc::dateToDays('01',$month,$year) - 6;
  1139.             } else {
  1140.                 $curr_day = Date_Calc::dateToDays('01',$month,$year)
  1141.                     - Date_Calc::firstOfMonthWeekday($month,$year) + 1;
  1142.             }
  1143.         } else {
  1144.             $curr_day = (Date_Calc::dateToDays('01',$month,$year)
  1145.                 - Date_Calc::firstOfMonthWeekday($month,$year));
  1146.         }
  1147.  
  1148.         // number of days in this month
  1149.         $daysInMonth = Date_Calc::daysInMonth($month,$year);
  1150.  
  1151.         $weeksInMonth = Date_Calc::weeksInMonth($month,$year);
  1152.         for($row_counter=0; $row_counter < $weeksInMonth; $row_counter++) {
  1153.             for($column_counter=0; $column_counter <= 6; $column_counter++) {
  1154.                 $month_array[$row_counter][$column_counter] =
  1155.                     Date_Calc::daysToDate($curr_day,$format);
  1156.                 $curr_day++;
  1157.             }
  1158.         }
  1159.  
  1160.         return $month_array;
  1161.     } // end func getCalendarMonth
  1162.  
  1163.     /**
  1164.      * Return a set of arrays to construct a calendar year for
  1165.      * the given date.
  1166.      *
  1167.      * @param string year in format CCYY, default current local year
  1168.      * @param string format for returned date
  1169.      *
  1170.      * @access public
  1171.      *
  1172.      * @return array $year[$month][$row][$col]
  1173.      */
  1174.  
  1175.     function getCalendarYear($year='',$format='%Y%m%d')
  1176.     {
  1177.         if (empty($year)) {
  1178.             $year = Date_Calc::dateNow('%Y');
  1179.         }
  1180.  
  1181.         $year_array = array();
  1182.  
  1183.         for($curr_month=0; $curr_month <=11; $curr_month++) {
  1184.             $year_array[$curr_month] =
  1185.                 Date_Calc::getCalendarMonth(sprintf('%02d',$curr_month+1),$year,$format);
  1186.         }
  1187.  
  1188.         return $year_array;
  1189.     } // end func getCalendarYear
  1190.  
  1191.     /**
  1192.      * Converts a date to number of days since a
  1193.      * distant unspecified epoch.
  1194.      *
  1195.      * @param string day in format DD
  1196.      * @param string month in format MM
  1197.      * @param string year in format CCYY
  1198.      *
  1199.      * @access public
  1200.      *
  1201.      * @return integer number of days
  1202.      */
  1203.  
  1204.     function dateToDays($day,$month,$year)
  1205.     {
  1206.  
  1207.         $century = (int) substr($year,0,2);
  1208.         $year = (int) substr($year,2,2);
  1209.  
  1210.         if ($month > 2) {
  1211.             $month -= 3;
  1212.         } else {
  1213.             $month += 9;
  1214.             if ($year) {
  1215.                 $year--;
  1216.             } else {
  1217.                 $year = 99;
  1218.                 $century --;
  1219.             }
  1220.         }
  1221.  
  1222.         return (floor(( 146097 * $century) / 4 ) +
  1223.             floor(( 1461 * $year) / 4 ) +
  1224.             floor(( 153 * $month + 2) / 5 ) +
  1225.             $day + 1721119);
  1226.     } // end func dateToDays
  1227.  
  1228.     /**
  1229.      * Converts number of days to a distant unspecified epoch.
  1230.      *
  1231.      * @param int number of days
  1232.      * @param string format for returned date
  1233.      *
  1234.      * @access public
  1235.      *
  1236.      * @return string date in specified format
  1237.      */
  1238.  
  1239.     function daysToDate($days,$format='%Y%m%d')
  1240.     {
  1241.  
  1242.         $days       -=  1721119;
  1243.         $century    =   floor(( 4 * $days - 1) / 146097);
  1244.         $days       =   floor(4 * $days - 1 - 146097 * $century);
  1245.         $day        =   floor($days / 4);
  1246.  
  1247.         $year       =   floor(( 4 * $day +  3) / 1461);
  1248.         $day        =   floor(4 * $day +  3 - 1461 * $year);
  1249.         $day        =   floor(($day +  4) / 4);
  1250.  
  1251.         $month      =   floor(( 5 * $day - 3) / 153);
  1252.         $day        =   floor(5 * $day - 3 - 153 * $month);
  1253.         $day        =   floor(($day +  5) /  5);
  1254.  
  1255.         if ($month < 10) {
  1256.             $month +=3;
  1257.         } else {
  1258.             $month -=9;
  1259.             if ($year++ == 99) {
  1260.                 $year = 0;
  1261.                 $century++;
  1262.             }
  1263.         }
  1264.  
  1265.         $century = sprintf('%02d',$century);
  1266.         $year = sprintf('%02d',$year);
  1267.         return(Date_Calc::dateFormat($day,$month,$century.$year,$format));
  1268.     } // end func daysToDate
  1269.  
  1270.     /**
  1271.      * Calculates the date of the Nth weekday of the month,
  1272.      * such as the second Saturday of January 2000.
  1273.      *
  1274.      * @param string occurance: 1=first, 2=second, 3=third, etc.
  1275.      * @param string dayOfWeek: 0=Sunday, 1=Monday, etc.
  1276.      * @param string month in format MM
  1277.      * @param string year in format CCYY
  1278.      * @param string format for returned date
  1279.      *
  1280.      * @access public
  1281.      *
  1282.      * @return string date in given format
  1283.      */
  1284.  
  1285.     function NWeekdayOfMonth($occurance,$dayOfWeek,$month,$year,$format='%Y%m%d')
  1286.     {
  1287.         $year = sprintf('%04d',$year);
  1288.         $month = sprintf('%02d',$month);
  1289.  
  1290.         $DOW1day = sprintf('%02d',(($occurance - 1) * 7 + 1));
  1291.         $DOW1 = Date_Calc::dayOfWeek($DOW1day,$month,$year);
  1292.  
  1293.         $wdate = ($occurance - 1) * 7 + 1 +
  1294.                 (7 + $dayOfWeek - $DOW1) % 7;
  1295.  
  1296.         if ( $wdate > Date_Calc::daysInMonth($month,$year)) {
  1297.             return -1;
  1298.         } else {
  1299.             return(Date_Calc::dateFormat($wdate,$month,$year,$format));
  1300.         }
  1301.     } // end func NWeekdayOfMonth
  1302.  
  1303.     /**
  1304.      *  Formats the date in the given format, much like
  1305.      *  strfmt(). This function is used to alleviate the
  1306.      *  problem with 32-bit numbers for dates pre 1970
  1307.      *  or post 2038, as strfmt() has on most systems.
  1308.      *  Most of the formatting options are compatible.
  1309.      *
  1310.      *  formatting options:
  1311.      *
  1312.      *  %a        abbreviated weekday name (Sun, Mon, Tue)
  1313.      *  %A        full weekday name (Sunday, Monday, Tuesday)
  1314.      *  %b        abbreviated month name (Jan, Feb, Mar)
  1315.      *  %B        full month name (January, February, March)
  1316.      *  %d        day of month (range 00 to 31)
  1317.      *  %e        day of month, single digit (range 0 to 31)
  1318.      *  %E        number of days since unspecified epoch (integer)
  1319.      *             (%E is useful for passing a date in a URL as
  1320.      *             an integer value. Then simply use
  1321.      *             daysToDate() to convert back to a date.)
  1322.      *  %j        day of year (range 001 to 366)
  1323.      *  %m        month as decimal number (range 1 to 12)
  1324.      *  %n        newline character (\n)
  1325.      *  %t        tab character (\t)
  1326.      *  %w        weekday as decimal (0 = Sunday)
  1327.      *  %U        week number of current year, first sunday as first week
  1328.      *  %y        year as decimal (range 00 to 99)
  1329.      *  %Y        year as decimal including century (range 0000 to 9999)
  1330.      *  %%        literal '%'
  1331.      *
  1332.      * @param string day in format DD
  1333.      * @param string month in format MM
  1334.      * @param string year in format CCYY
  1335.      * @param string format for returned date
  1336.      *
  1337.      * @access public
  1338.      *
  1339.      * @return string date in given format
  1340.      */
  1341.  
  1342.     function dateFormat($day,$month,$year,$format)
  1343.     {
  1344.         if (!Date_Calc::isValidDate($day,$month,$year)) {
  1345.             $year = Date_Calc::dateNow('%Y');
  1346.             $month = Date_Calc::dateNow('%m');
  1347.             $day = Date_Calc::dateNow('%d');
  1348.         }
  1349.  
  1350.         $output = '';
  1351.  
  1352.         for($strpos = 0; $strpos < strlen($format); $strpos++) {
  1353.             $char = substr($format,$strpos,1);
  1354.             if ($char == '%') {
  1355.                 $nextchar = substr($format,$strpos + 1,1);
  1356.                 switch($nextchar) {
  1357.                     case 'a':
  1358.                         $output .= Date_Calc::getWeekdayAbbrname($day,$month,$year);
  1359.                         break;
  1360.                     case 'A':
  1361.                         $output .= Date_Calc::getWeekdayFullname($day,$month,$year);
  1362.                         break;
  1363.                     case 'b':
  1364.                         $output .= Date_Calc::getMonthAbbrname($month);
  1365.                         break;
  1366.                     case 'B':
  1367.                         $output .= Date_Calc::getMonthFullname($month);
  1368.                         break;
  1369.                     case 'd':
  1370.                         $output .= sprintf('%02d',$day);
  1371.                         break;
  1372.                     case 'e':
  1373.                         $output .= $day;
  1374.                         break;
  1375.                     case 'E':
  1376.                         $output .= Date_Calc::dateToDays($day,$month,$year);
  1377.                         break;
  1378.                     case 'j':
  1379.                         $output .= Date_Calc::julianDate($day,$month,$year);
  1380.                         break;
  1381.                     case 'm':
  1382.                         $output .= sprintf('%02d',$month);
  1383.                         break;
  1384.                     case 'n':
  1385.                         $output .= "\n";
  1386.                         break;
  1387.                     case "t":
  1388.                         $output .= "\t";
  1389.                         break;
  1390.                     case 'w':
  1391.                         $output .= Date_Calc::dayOfWeek($day,$month,$year);
  1392.                         break;
  1393.                     case 'U':
  1394.                         $output .= Date_Calc::weekOfYear($day,$month,$year);
  1395.                         break;
  1396.                     case 'y':
  1397.                         $output .= substr($year,2,2);
  1398.                         break;
  1399.                     case 'Y':
  1400.                         $output .= $year;
  1401.                         break;
  1402.                     case '%':
  1403.                         $output .= '%';
  1404.                         break;
  1405.                     default:
  1406.                         $output .= $char.$nextchar;
  1407.                 }
  1408.                 $strpos++;
  1409.             } else {
  1410.                 $output .= $char;
  1411.             }
  1412.         }
  1413.         return $output;
  1414.     } // end func dateFormat
  1415.  
  1416.     /**
  1417.      * Returns the current local year in format CCYY
  1418.      *
  1419.      * @access public
  1420.      *
  1421.      * @return string year in format CCYY
  1422.      */
  1423.  
  1424.     function getYear()
  1425.     {
  1426.         return Date_Calc::dateNow('%Y');
  1427.     } // end func getYear
  1428.  
  1429.     /**
  1430.      * Returns the current local month in format MM
  1431.      *
  1432.      * @access public
  1433.      *
  1434.      * @return string month in format MM
  1435.      */
  1436.  
  1437.     function getMonth()
  1438.     {
  1439.         return Date_Calc::dateNow('%m');
  1440.     } // end func getMonth
  1441.  
  1442.     /**
  1443.      * Returns the current local day in format DD
  1444.      *
  1445.      * @access public
  1446.      *
  1447.      * @return string day in format DD
  1448.      */
  1449.  
  1450.     function getDay()
  1451.     {
  1452.         return Date_Calc::dateNow('%d');
  1453.     } // end func getDay
  1454.  
  1455.     /**
  1456.      * Returns the full month name for the given month
  1457.      *
  1458.      * @param string month in format MM
  1459.      *
  1460.      * @access public
  1461.      *
  1462.      * @return string full month name
  1463.      */
  1464.  
  1465.     function getMonthFullname($month)
  1466.     {
  1467.         $month = (int)$month;
  1468.  
  1469.         if (empty($month)) {
  1470.             $month = (int) Date_Calc::dateNow('%m');
  1471.         }
  1472.  
  1473.         $month_names = Date_Calc::getMonthNames();
  1474.  
  1475.         return $month_names[$month];
  1476.         // getMonthNames returns months with correct indexes
  1477.         //return $month_names[($month - 1)];
  1478.     } // end func getMonthFullname
  1479.  
  1480.     /**
  1481.      * Returns the abbreviated month name for the given month
  1482.      *
  1483.      * @param string month in format MM
  1484.      * @param int optional length of abbreviation, default is 3
  1485.      *
  1486.      * @access public
  1487.      *
  1488.      * @return string abbreviated month name
  1489.      * @see Date_Calc::getMonthFullname
  1490.      */
  1491.  
  1492.     function getMonthAbbrname($month,$length=3)
  1493.     {
  1494.         $month = (int)$month;
  1495.  
  1496.         if (empty($month)) {
  1497.             $month = Date_Calc::dateNow('%m');
  1498.         }
  1499.  
  1500.         return substr(Date_Calc::getMonthFullname($month), 0, $length);
  1501.     } // end func getMonthAbbrname
  1502.  
  1503.     /**
  1504.      * Returns the full weekday name for the given date
  1505.      *
  1506.      * @param string day in format DD, default is current local day
  1507.      * @param string month in format MM, default is current local month
  1508.      * @param string year in format CCYY, default is current local year
  1509.      *
  1510.      * @access public
  1511.      *
  1512.      * @return string full month name
  1513.      */
  1514.  
  1515.     function getWeekdayFullname($day='',$month='',$year='')
  1516.     {
  1517.         if (empty($year)) {
  1518.             $year = Date_Calc::dateNow('%Y');
  1519.         }
  1520.         if (empty($month)) {
  1521.             $month = Date_Calc::dateNow('%m');
  1522.         }
  1523.         if (empty($day)) {
  1524.             $day = Date_Calc::dateNow('%d');
  1525.         }
  1526.  
  1527.         $weekday_names = Date_Calc::getWeekDays();
  1528.         $weekday = Date_Calc::dayOfWeek($day,$month,$year);
  1529.  
  1530.         return $weekday_names[$weekday];
  1531.     } // end func getWeekdayFullname
  1532.  
  1533.     /**
  1534.      * Returns the abbreviated weekday name for the given date
  1535.      *
  1536.      * @param string day in format DD, default is current local day
  1537.      * @param string month in format MM, default is current local month
  1538.      * @param string year in format CCYY, default is current local year
  1539.      * @param int optional length of abbreviation, default is 3
  1540.      *
  1541.      * @access public
  1542.      *
  1543.      * @return string full month name
  1544.      * @see Date_Calc::getWeekdayFullname
  1545.      */
  1546.  
  1547.     function getWeekdayAbbrname($day='',$month='',$year='',$length=3)
  1548.     {
  1549.         if (empty($year)) {
  1550.             $year = Date_Calc::dateNow('%Y');
  1551.         }
  1552.         if (empty($month)) {
  1553.             $month = Date_Calc::dateNow('%m');
  1554.         }
  1555.         if (empty($day)) {
  1556.             $day = Date_Calc::dateNow('%d');
  1557.         }
  1558.  
  1559.         return substr(Date_Calc::getWeekdayFullname($day,$month,$year),0,$length);
  1560.     } // end func getWeekdayFullname
  1561.  
  1562.     /**
  1563.     * Returns the numeric month from the month name or an abreviation
  1564.     *
  1565.     * Both August and Aug would return 8.
  1566.     * Month name is case insensitive.
  1567.     *
  1568.     * @param    string  month name
  1569.     * @return   integer month number
  1570.     */
  1571.     function getMonthFromFullName($month)
  1572.     {
  1573.         $month = strtolower($month);
  1574.         $months = Date_Calc::getMonthNames();
  1575.         while(list($id, $name) = each($months)) {
  1576.             if (ereg($month, strtolower($name))) {
  1577.                 return($id);
  1578.             }
  1579.         }
  1580.  
  1581.         return(0);
  1582.     } // end func getMonthFromFullName
  1583.  
  1584.     /**
  1585.     * Returns an array of month names
  1586.     *
  1587.     * Used to take advantage of the setlocale function to return
  1588.     * language specific month names.
  1589.     * XXX cache values to some global array to avoid preformace
  1590.     * hits when called more than once.
  1591.     *
  1592.     * @returns array An array of month names
  1593.     */
  1594.     function getMonthNames()
  1595.     {
  1596.         for($i=1;$i<13;$i++) {
  1597.             $months[$i] = strftime('%B', mktime(0, 0, 0, $i, 1, 2001));
  1598.         }
  1599.         return($months);
  1600.     } // end func getMonthNames
  1601.  
  1602.     /**
  1603.     * Returns an array of week days
  1604.     *
  1605.     * Used to take advantage of the setlocale function to
  1606.     * return language specific week days
  1607.     * XXX cache values to some global array to avoid preformace
  1608.     * hits when called more than once.
  1609.     *
  1610.     * @returns array An array of week day names
  1611.     */
  1612.     function getWeekDays()
  1613.     {
  1614.         for($i=0;$i<7;$i++) {
  1615.             $weekdays[$i] = strftime('%A', mktime(0, 0, 0, 1, $i, 2001));
  1616.         }
  1617.         return($weekdays);
  1618.     } // end func getWeekDays
  1619.  
  1620.     /**
  1621.      * Converts from Gregorian Year-Month-Day to
  1622.      * ISO YearNumber-WeekNumber-WeekDay
  1623.      *
  1624.      * Uses ISO 8601 definitions.
  1625.      * Algorithm from Rick McCarty, 1999 at
  1626.      * http://personal.ecu.edu/mccartyr/ISOwdALG.txt
  1627.      *
  1628.      * @param string day in format DD
  1629.      * @param string month in format MM
  1630.      * @param string year in format CCYY
  1631.      * @return string
  1632.      * @access public
  1633.      */
  1634.     // Transcribed to PHP by Jesus M. Castagnetto (blame him if it is fubared ;-)
  1635.     function gregorianToISO($day,$month,$year) {
  1636.         $mnth = array (0,31,59,90,120,151,181,212,243,273,304,334);
  1637.         $y_isleap = Date_Calc::isLeapYear($year);
  1638.         $y_1_isleap = Date_Calc::isLeapYear($year - 1);
  1639.         $day_of_year_number = $day + $mnth[$month - 1];
  1640.         if ($y_isleap && $month > 2) {
  1641.             $day_of_year_number++;
  1642.         }
  1643.         // find Jan 1 weekday (monday = 1, sunday = 7)
  1644.         $yy = ($year - 1) % 100;
  1645.         $c = ($year - 1) - $yy;
  1646.         $g = $yy + intval($yy/4);
  1647.         $jan1_weekday = 1 + intval((((($c / 100) % 4) * 5) + $g) % 7);
  1648.         // weekday for year-month-day
  1649.         $h = $day_of_year_number + ($jan1_weekday - 1);
  1650.         $weekday = 1 + intval(($h - 1) % 7);
  1651.         // find if Y M D falls in YearNumber Y-1, WeekNumber 52 or
  1652.         if ($day_of_year_number <= (8 - $jan1_weekday) && $jan1_weekday > 4){
  1653.             $yearnumber = $year - 1;
  1654.             if ($jan1_weekday == 5 || ($jan1_weekday == 6 && $y_1_isleap)) {
  1655.                 $weeknumber = 53;
  1656.             } else {
  1657.                 $weeknumber = 52;
  1658.             }
  1659.         } else {
  1660.             $yearnumber = $year;
  1661.         }
  1662.         // find if Y M D falls in YearNumber Y+1, WeekNumber 1
  1663.         if ($yearnumber == $year) {
  1664.             if ($y_isleap) {
  1665.                 $i = 366;
  1666.             } else {
  1667.                 $i = 365;
  1668.             }
  1669.             if (($i - $day_of_year_number) < (4 - $weekday)) {
  1670.                 $yearnumber++;
  1671.                 $weeknumber = 1;
  1672.             }
  1673.         }
  1674.         // find if Y M D falls in YearNumber Y, WeekNumber 1 through 53
  1675.         if ($yearnumber == $year) {
  1676.             $j = $day_of_year_number + (7 - $weekday) + ($jan1_weekday - 1);
  1677.             $weeknumber = intval($j / 7);
  1678.             if ($jan1_weekday > 4) {
  1679.                 $weeknumber--;
  1680.             }
  1681.         }
  1682.         // put it all together
  1683.         if ($weeknumber < 10)
  1684.             $weeknumber = '0'.$weeknumber;
  1685.         return "{$yearnumber}-{$weeknumber}-{$weekday}";
  1686.     }
  1687.  
  1688.     /**
  1689.     * Determines julian date of the given season
  1690.     * Adapted from previous work in Java by James Mark Hamilton, mhamilton@qwest.net
  1691.     *
  1692.     * @author Robert Butler <rob@maxwellcreek.org>
  1693.     *
  1694.     * @param string is VERNALEQUINOX, SUMMERSOLSTICE, AUTUMNALEQUINOX, or WINTERSOLSTICE.
  1695.     * @param string year in format CCYY, must be a calendar year between -1000BC and 3000AD.
  1696.     *
  1697.     * @access public
  1698.     *
  1699.     * @return float $juliandate
  1700.     */
  1701.  
  1702.     function dateSeason ($season, $year = '') {
  1703.             if ($year == '') {
  1704.                     $year = Date_Calc::dateNow('%Y');
  1705.             }
  1706.  
  1707.             if (($year >= -1000) && ($year <= 1000)) {
  1708.                     $y = $year / 1000.0;
  1709.                     if ($season == 'VERNALEQUINOX') {
  1710.                             $juliandate = (((((((-0.00071 * $y) - 0.00111) * $y) + 0.06134) * $y) + 365242.1374) * $y) + 1721139.29189;
  1711.                     } else if ($season == 'SUMMERSOLSTICE') {
  1712.                             $juliandate = ((((((( 0.00025 * $y) + 0.00907) * $y) - 0.05323) * $y) + 365241.72562) * $y) + 1721233.25401;
  1713.                     } else if ($season == 'AUTUMNALEQUINOX') {
  1714.                             $juliandate = ((((((( 0.00074 * $y) - 0.00297) * $y) - 0.11677) * $y) + 365242.49558) * $y) + 1721325.70455;
  1715.                     } else if ($season == 'WINTERSOLSTICE') {
  1716.                             $juliandate = (((((((-0.00006 * $y) - 0.00933) * $y) - 0.00769) * $y) + 365242.88257) * $y) + 1721414.39987;
  1717.                     }
  1718.             } elseif (($year > 1000) && ($year <= 3000)) {
  1719.                     $y = ($year - 2000) / 1000;
  1720.                     if ($season == 'VERNALEQUINOX') {
  1721.                             $juliandate = (((((((-0.00057 * $y) - 0.00411) * $y) + 0.05169) * $y) + 365242.37404) * $y) + 2451623.80984;
  1722.                     } else if ($season == 'SUMMERSOLSTICE') {
  1723.                             $juliandate = (((((((-0.0003 * $y) + 0.00888) * $y) + 0.00325) * $y) + 365241.62603) * $y) + 2451716.56767;
  1724.                     } else if ($season == 'AUTUMNALEQUINOX') {
  1725.                             $juliandate = ((((((( 0.00078 * $y) + 0.00337) * $y) - 0.11575) * $y) + 365242.01767) * $y) + 2451810.21715;
  1726.                     } else if ($season == 'WINTERSOLSTICE') {
  1727.                             $juliandate = ((((((( 0.00032 * $y) - 0.00823) * $y) - 0.06223) * $y) + 365242.74049) * $y) + 2451900.05952;
  1728.                     }
  1729.             }
  1730.  
  1731.             return ($juliandate);
  1732.     } // end func dateSeason
  1733.  
  1734. } // end class Date_Calc
  1735.  
  1736. ?>
  1737.